home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
docs
/
ippon
/
eshot
/
6
/
eshot.c
next >
Wrap
C/C++ Source or Header
|
2000-07-07
|
5KB
|
230 lines
/* eshot.c */
#include <stdio.h>
#include <stdlib.h>
#include <math.h> /* sin,cos を使うために */
#include <sys/iocs.h>
#include "XSP2lib.H"
#define PCG_MAX 32 /* パターンデータの個数 */
static char pcg_alt[PCG_MAX + 1]; /* PCG配置管理テーブル */
static char pcg_dat[PCG_MAX * 128]; /* PCGデータファイル読み込みバッファ */
static unsigned short pal_dat[16][15]; /* パレットデータ */
#define ESHOT_MAX 200 /* 敵弾最大数 */
#define ESHOT_SPEED 0.75 /* 敵弾の速度 */
/* 敵弾構造体 */
typedef struct _eshot {
signed short x; /* 敵弾のX座標 */
signed short y; /* 〃 Y座標 */
unsigned char type; /* 〃 種類(=0 なら未使用) */
signed int lx, ly; /* 32bit X,Y 座標 ( l = longword ) */
signed int vx, vy; /* 32bit X,Y 速度 ( v = velocity ) */
struct _eshot *next; /* 次の構造体へのポインタ */
} ESHOT;
ESHOT *eshot_top; /* 使用中のワークのリスト */
ESHOT *eshot_null_top; /* 未使用ワークのリスト */
ESHOT eshot[ESHOT_MAX]; /* ワーク */
typedef struct {
signed int x, y;
} VECTOR;
VECTOR xytable[256]; /* sin,cos テーブル */
/* ゲーム開始時に呼ばれる */
void EshotInit (void)
{
int i;
/* リストをつなげる */
eshot_top = NULL;
eshot_null_top = eshot;
for (i = 0; i < ESHOT_MAX; i++)
eshot[i].next = &eshot[i + 1]; /* 次を指すようにする */
eshot[ESHOT_MAX - 1].next = NULL; /* 「一番最後の次」はない */
}
/* 敵弾出現時に呼ばれる */
/* 引き数 : 種類, X座標, Y座標, 角度 */
void EshotAlloc (unsigned char type, signed short x, signed short y, unsigned char angle)
{
ESHOT *p;
if (eshot_null_top == NULL) /* ワークの空きはあるか? */
return;
p = eshot_null_top;
eshot_null_top = p->next;
p->next = eshot_top;
eshot_top = p;
p->lx = (x - 8) * 65536; /* (8,8) がスプライト座標の中心なので補正 */
p->ly = (y - 8) * 65536;
p->vx = xytable[angle].x;
p->vy = xytable[angle].y;
p->type = type;
}
/* 垂直同期ごとに呼ばれる */
void EshotMove (void)
{
ESHOT *p, *q;
p = eshot_top; /* 現在注目しているワーク */
q = NULL; /* 1つ前のワーク(ワーク削除時に必要) */
while (p != NULL) {
p->lx += p->vx; /* vx だけ移動 */
p->ly += p->vy; /* vy だけ移動 */
p->x = p->lx / 65536; /* lx の整数部を取り出して x に */
p->y = p->ly / 65536; /* ly の整数部を取り出して y に */
/* 敵弾が画面外に出たか? */
if ((p->x < 0) || (p->x > 256 + 16) || (p->y < 0) || (p->y > 256 + 16)) {
/* 画面外に出たので消去 */
if (q == NULL) { /* リストの一番最初を削除 */
eshot_top = p->next;
p->next = eshot_null_top;
eshot_null_top = p;
q = NULL;
p = eshot_top;
} else {
q->next = p->next;
p->next = eshot_null_top;
eshot_null_top = p;
p = q->next;
}
} else {
xsp_set (p->x, p->y, p->type, 0x033f);
q = p;
p = p->next;
}
}
}
int main (int argc, char *argv[])
{
FILE *fp;
int i, j;
int game_over = 0;
unsigned char angle = 0; /* 次に撃つ弾の角度 */
unsigned char type = 1; /* 次に撃つ弾の種類 */
int sprites; /* スプライトの枚数 */
if (argc != 1) {
printf (
"敵弾テストその6 ESHOT.X\n"
" programmed by Mitsuky <FreeSoftware>\n"
"空きのワークもリスト構造で管理するようにした\n"
);
exit (-1);
}
printf ("データテーブルを作成します。\n");
for (i = 0; i < 256; i++) {
xytable[i].x = (signed int) (cos (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
xytable[i].y = (signed int) (sin (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
}
_iocs_crtmod (10); /* 256x256ドット グラフィック画面 256色 2画面 */
_iocs_g_clr_on (); /* グラフィック画面の初期化 */
_iocs_sp_init (); /* スプライトの初期化 */
_iocs_sp_on ();
/* pcg_dat にパターンデータを読み込む */
fp = fopen ("ESHOT.SP", "rb");
fread (pcg_dat, sizeof (char), PCG_MAX * 128, fp);
fclose (fp);
/* pal_buf に一旦パレットデータを読み込む */
fp = fopen ("ESHOT.PAL", "rb");
fread (pal_dat, sizeof (unsigned short), 16 * 15, fp);
fclose (fp);
/* パレットデータを定義 */
/* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
{
unsigned short *p = (unsigned short *) pal_dat;
for (i = 1; i < 15; i++)
for (j = 0; j < 16; j++)
_iocs_spalet (0x80000000 | j, i, *p++);
}
xsp_on ();
xsp_mode (3);
/* パターンデータを定義 */
xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
/* グラフィック画面に線を引く */
{
struct _lineptr lp;
lp.x1 = 0;
lp.y1 = 128;
lp.x2 = 255;
lp.y2 = 128;
lp.color = 15;
lp.linestyle = 0xaaaa;
_iocs_line (&lp);
lp.x1 = 128;
lp.y1 = 0;
lp.x2 = 128;
lp.y2 = 255;
_iocs_line (&lp);
}
printf ("ジョイスティックの\n"
" [B] ボタンを押すと弾を撃ちます\n"
" [A] ボタンを押すと終了します\n");
EshotInit ();
do {
xsp_vsync (0); /* 垂直同期待ち */
j = _iocs_joyget (0); /* ジョイスティック0番 */
/* [A] ボタンが押されたか? */
if ((j & 0b00100000) == 0)
game_over = !0; /* ゲームオーバーに */
/* [B] ボタンが押されたか? */
if ((j & 0b1000000) == 0) {
EshotAlloc (type, 144, 144, angle); /* 種類 type の敵弾を座標(144,144)、角度 angle で発生 */
angle += 8; /* 角度を進める */
type++; /* 種類を進める(意味無し) */
if (type > 5)
type = 1;
}
EshotMove ();
sprites = xsp_out (); /* 表示 */
printf ("弾数 = %3d \n\x0b", sprites);
/* 0x0b はカーソルを1行上に移動する */
/* Human68K ユーザーズマニュアルの付録 ASCII 制御コードの欄参照 */
} while (!game_over);
xsp_off ();
_iocs_crtmod (16);
return (0);
}